package com.jiao.table.lua;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.jiao.comm.exception.LuaSyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Include 增强.
 * 用于 lua 引入别的 lua 脚本, 因为 Redis 为了数据复制中限制了 require 语法。
 * 所以这里增强对文件的引入
 * //TODO 增强放到缓存读写模块
 * @Author: vincent.jiao
 * @Date: 2021/5/31
 */
public class IncludeSyntaxEnhance implements LuaSyntaxEnhance {
    String key = "include";
    Pattern pattern = Pattern.compile("(include\\(['|\"]\\w+.lua['|\"]\\);?)");
    Map<String, String> fileAndContentMap = null;
    static IncludeSyntaxEnhance includeSyntaxEnhance = new IncludeSyntaxEnhance();

    public IncludeSyntaxEnhance(){
        //加入到 lua 加载器
//        LuaScriptLoad.getInstance().setSyntaxEnhance(this);
    }

    /**
     * 替换 include 命令为指定脚本内容.
     * @param luaScript lua 脚本内容
     * @return
     */
    @Override
    public String syntaxEnhance(String luaScript) {

        Map<String, String> includeMap = new HashMap<>();

        while (true){
            Matcher matcher = pattern.matcher(luaScript);
            int findCount = 0;

            while (matcher.find()) {
                String include = matcher.group(0);
                String fileName = include;
                fileName = fileName.substring(fileName.indexOf('(')+1, fileName.lastIndexOf(')'));
                fileName = fileName.substring(1).substring(0, fileName.length() - 2);
                includeMap.put(fileName, include);
                ++findCount;
            }

            if (findCount == 0){
                break;
            }

            if (CollectionUtil.isNotEmpty(includeMap)){
                for(String item : includeMap.keySet()){
                    String script = fileAndContentMap.get(item);

                    if(StrUtil.isEmpty(script)){
                        throw new LuaSyntaxException("未找到 "+item+" 文件, 引入失败!");
                    }

                    luaScript = luaScript.replace(includeMap.get(item), script);
                }
            }

            includeMap.clear();
        }

        return luaScript;
    }
}
